<template>
  <el-container>
    <el-header>
      <el-page-header content="excel规则设计" @back="onBack"></el-page-header>
      <div>
        <el-button type="primary" @click="exportData">提交</el-button>
      </div>
    </el-header>
    <splitpanes @resize="resize" class="default-theme" >
      <pane size="20">
          <el-scrollbar :height="h">
            <el-container>
              <el-main style="padding: 0px">
                <el-tree
                  ref="group"
                  class="menu"
                  node-key="id"
                  draggable
                  :data="groupData"
                  :default-expand-all="true"
                  :highlight-current="true"
                  :expand-on-click-node="false"
                  :allow-drag="allowDrag"
                  :allow-drop="allowDrop"
                  @node-click="groupClick"
                  @node-drag-start="onStart"
                  :key="treeKey"
                >
                  <template #default="{ node, data }">
                    <span>
                      <span style="margin-right: 2px">
                        <el-icon>
                          <component :is="data.icon" />
                        </el-icon>
                      </span>
                      <span>{{ node.label }}</span>
                      <span v-if="data.position">{{
                        `(${data.position || ""}) `
                      }}</span>
                    </span>
                  </template>
                </el-tree>
              </el-main>
            </el-container>
                 </el-scrollbar
          >
          </pane>
          <pane size="60" style="position: relative;">
        <div
          style="position: absolute; top: 0; width: 100%"
          id="luckysheet"
        ></div>
      </pane>
      <pane size = '20'>
          <el-scrollbar :height="h">
            <el-card>
              <dataSet
                v-model="form"
                v-if="nodeType == 'table'"
                :configData="configData"
                @change-range="changeRange($event, 'table')"
              />
              <field
                v-model="form"
                v-if="nodeType == 'field'"
                :configData="configData"
                @change-range="changeRange($event, 'field')"
              />
            </el-card>
          </el-scrollbar>
        </pane>
    </splitpanes>
  </el-container>
</template>
  
<script setup>
import { ref, onMounted, computed, watch, nextTick } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElNotification } from "element-plus";
import LuckyExcel from "luckyexcel";
import API from "@/api/model/luckysheet.js";
import {
  Plus,
  Edit,
  Delete,
  Check,
  Close,
  ArrowLeftBold,
  ArrowRightBold,
} from "@element-plus/icons-vue";
import useTabs from "@/utils/useTabs";
import { deepClone } from "@/utils/arr";
import { extractNodesAndFields } from "./analysis.js";
import { check } from "./check.js";
import dataSet from "./commpoents/dataSet.vue";
import field from "./commpoents/field.vue";
const router = useRouter();
const props = defineProps({
  data: {
    type: Object,
    defalut: {},
  },
  jsonContent: {
    type: Object,
    defalut: {},
  },
});
const h = computed(() => {
  let height;
  var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
  if (!iOS) {
    height = window.innerHeight;
  } else {
    height = screen.height;
  }
  return (height - 110) * 0.95;
});
const groupData = ref([]);
const group = ref(null);
const nodeType = ref();
const dragTargetNode = ref({}); //拖拽节点
const form = ref({});
const jsonData = ref({});
const nodesArray = ref([]);
const fieldsArray = ref([]);
const configData = ref([]);
const needInit = ref(false);
const treeKey = ref(0);
const resize = (e)=>{
  luckysheet.resize()
}
const onBack = () => {
  useTabs.close();
  router.back();
};
// !!! create luckysheet after mounted
onMounted(() => {
  window.excelUpload = excelUpload;
  getInit();
});
const getInit = async () => {
  let res = await API.excelConfig.init.post({ id: props.data.id });
  if (res.code == 200) {
    if (res.bean.pageConfigFile.endsWith(".xlsx")) {
      getExcel(res.bean.pageConfigFile);
      needInit.value = true;
    } else {
      getJson(res.bean.pageConfigFile);
    }
    groupData.value = res.dataList;
    nextTick(() => {
      group.value.setCurrentKey(groupData.value[0].id); // 默认选中节点第一个
    });
    configData.value = res.configData;
    nodesArray.value = extractNodesAndFields(res.importTableList).nodesArray;
    fieldsArray.value = extractNodesAndFields(res.importTableList).fieldsArray;
  }
};
const allowDrag = (node) => {
  return true;
};
const allowDrop = (draggingNode, dropNode, type) => {
  return false;
};
const getExcel = async (path) => {
  let params = {
    downloadFileName: path,
    isDown: false,
  };
  let res = await API.excelConfig.uploadfile.post(params);
  const file = new window.File([res], "文件", { type: res.type });
  transformToLucky(file);
};
const getJson = async () => {
  let res = await API.excelConfig.loadImportRuleFile.post({
    id: props.data.id,
  });
  if (res.code == 200) {
    createLuckysheet(JSON.parse(res.jsonContent));
  }
};
const createLuckysheet = (val) => {
  window.luckysheet.destroy();
  window.luckysheet.create({
    container: "luckysheet",
    data: val,
    lang: "zh",
    showinfobar: false,
    showtoolbarConfig: {
      currencyFormat: false, //货币格式
      percentageFormat: false, //百分比格式
      numberDecrease: false, // '减少小数位数'
      numberIncrease: false, // '增加小数位数
      postil: false, //'批注'
      pivotTable: false, //'数据透视表'
    },
    allowUpdate: true,
    hook: {
      cellDragStop(cell, position) {
        console.log('cell')
        dragStop(cell, position);
      },
      cellEditBefore: function (range) {
        // console.log(luckysheet.setCellValue(0, 0,1))
        console.log(range);
      },
      cellUpdateBefore: function (r, c, value, isRefresh) {
        // console.log("cellUpdateBefore", r, c, value, isRefresh);
      },
      cellUpdated: function (r, c, oldValue, newValue, isRefresh) {
        if (oldValue && oldValue.uid && newValue.v === undefined) {
          updateCell(oldValue, newValue);
        }
      },
      rangeSelect: function (index, sheet) {
        // console.info(index, sheet);
      },
      cellMousedown: function (cell, position) {
        mouseDown(cell, position);
      },
      workbookCreateAfter: function (options) {
        if (needInit.value) {
          nodesArray.value.forEach((ele) => {
            if (ele.startRegion) {
              changeRange({ newValue: ele.startRegion }, "table", ele);
            }
          });
          fieldsArray.value.forEach((ele) => {
            if (ele.mapColumn) {
              changeRange({ newValue: ele.mapColumn }, "field", ele);
            }
          });
        }
      },
    },
  });
};
const replaceCell = (val) => {
  const pattern = /\[\[.*?\]\]|{{.*?}}/g;
  let str = luckysheet
    .getCellValue(Number(val.charAt(1)) - 1, val.charAt(0).charCodeAt(0) - 65)
    .replace(pattern, "");
  luckysheet.setCellValue(
    Number(val.charAt(1)) - 1,
    val.charAt(0).charCodeAt(0) - 65,
    { m: str, v: str }
  );
};
const onStart = (node) => {
  if (!node) {
    return;
  }
  dragTargetNode.value = node.data;
};
const groupClick = (node) => {
  if (node.nodeType === "table") {
    form.value =
      nodesArray.value[
        nodesArray.value.findIndex((ele) => ele.uid === node.parentId + node.id)
      ];
  } else {
    form.value =
      fieldsArray.value[
        fieldsArray.value.findIndex(
          (ele) => ele.uid === node.parentId + node.id
        )
      ];
  }
  nodeType.value = node.nodeType;
};
const changeRange = (val, type, data) => {
  let formData = data ? data : form.value;
  let cell = luckysheet.getCellValue(
    Number(val.newValue.charAt(1)) - 1,
    val.newValue.charAt(0).charCodeAt(0) - 65
  );
  let mv = cell || "";
  const pattern = /\[\[.*?\]\]|{{.*?}}/g;
  mv = mv.replace(pattern, "");
  if (type === "table") {
    mv = (mv || "") + `[[${formData.id}]]`;
  } else {
    mv = (mv || "") + `{{${formData.id}}}`;
  }
  luckysheet.setCellValue(
    Number(val.newValue.charAt(1)) - 1,
    val.newValue.charAt(0).charCodeAt(0) - 65,
    { m: mv, v: mv, uid: formData.parentId + formData.id }
  );
  groupData.value.forEach((ele) => {
    changeTreeNodeLabel(val.newValue, formData.parentId + formData.id, ele);
  });
  if (val.oldValue) {
    replaceCell(val.oldValue);
  }
};
const excelUpload = (file) => {
  if (file == null || file == undefined) {
    alert("请导入");
    return;
  }
  let suffixArr = file.name.split("."),
    suffix = suffixArr[suffixArr.length - 1];
  if (suffix != "xlsx") {
    alert("请上传excel文件");
    return;
  }
  saveUploadExcel(file);
  transformToLucky(file);
};
const transformToLucky = (file) => {
  LuckyExcel.transformExcelToLucky(file, function (exportJson, luckysheetfile) {
    if (exportJson.sheets == null || exportJson.sheets.length == 0) {
      alert("不支持xls文件");
      return;
    }
    jsonData.value = exportJson;
    console.log(exportJson.sheets);
    createLuckysheet(exportJson.sheets);
  });
};
const updateCell = (oldValue, newValue) => {
  groupData.value.forEach((ele) => {
    changeTreeNodeLabel("", oldValue.uid, ele);
  });
  const arrayToSearch = /\[\[/.test(oldValue.v)
    ? nodesArray.value
    : fieldsArray.value;
  const field = /\[\[/.test(oldValue.v) ? "startRegion" : "mapColumn";
  arrayToSearch.find((ele) => ele.uid === oldValue.uid)[field] = "";
};
const mouseDown = (cell, position) => {
  if (cell && cell.v && (cell.v.includes("[[") || cell.v.includes("}}"))) {
    const arrayToSearch = /\[\[/.test(cell.v)
      ? nodesArray.value
      : fieldsArray.value;
    const foundElement = arrayToSearch.find((ele) => ele.uid === cell.uid);
    if (foundElement) {
      form.value = foundElement;
    }
    nodeType.value = /\[\[/.test(cell.v) ? "table" : "field";
  }
};
const dragStop = (cell, position) => {
  const { r, c } = position;
  if (dragTargetNode.value) {
    const mv = deepClone(cell) || {};
    if (dragTargetNode.value.position) {
      replaceCell(dragTargetNode.value.position);
    }
    if (dragTargetNode.value.nodeType === "table") {
      mv.m = (mv.m || "") + `[[${dragTargetNode.value.id}]]`;
      nodesArray.value[
        nodesArray.value.findIndex(
          (ele) =>
            ele.uid === dragTargetNode.value.parentId + dragTargetNode.value.id
        )
      ].startRegion = String.fromCharCode(c + 65) + (r + 1);
    } else {
      mv.m = (mv.m || "") + `{{${dragTargetNode.value.id}}}`;
      fieldsArray.value[
        fieldsArray.value.findIndex(
          (ele) =>
            ele.uid === dragTargetNode.value.parentId + dragTargetNode.value.id
        )
      ].mapColumn = String.fromCharCode(c + 65) + (r + 1);
    }
    mv.v = mv.m;
    mv.uid = dragTargetNode.value.parentId + dragTargetNode.value.id;
    groupData.value.forEach((ele) => {
      changeTreeNodeLabel(String.fromCharCode(c + 65) + (r + 1), mv.uid, ele);
    });
    luckysheet.setCellValue(r, c, {
      ...mv,
    });
    dragTargetNode.value = null;
  }
};
const changeTreeNodeLabel = (position, id, tree) => {
  if (tree.parentId + tree.id === id) {
    tree.position = position;
    treeKey.value += 1;
    return;
  }
  // 如果没有匹配，递归检查每个子节点
  if (tree.children) {
    for (let i = 0; i < tree.children.length; i++) {
      changeTreeNodeLabel(position, id, tree.children[i]);
    }
  }
};
const saveUploadExcel = async (file) => {
  let param = {
    file: file,
    id: props.data.id,
  };
  let res = await API.saveUploadxcelFile.post(param);
};
//上传
const exportData = async () => {
  let param = {
    bean: { id: props.data.id },
    dataList: nodesArray.value,
    dtlList: fieldsArray.value,
    excelData: JSON.stringify(luckysheet.getAllSheets()),
  };
  console.log(param)
  let res = await API.excelConfig.saveConfigRule.post(param);
  if (res.code == 200) {
    ElNotification.success({
      title: "",
      message: "保存成功！",
      duration: 2000,
    });
  }
};
</script>
  
<style lang="less"  scoped>
#luckysheet {
  margin: 0px;
  padding: 0px;
  position: absolute;
  width: 100%;
  left: 0px;
  top: 30px;
  bottom: 0px;
}

#uploadBtn {
  font-size: 16px;
}

#tip {
  position: absolute;
  z-index: 1000000;
  left: 0px;
  top: 0px;
  bottom: 0px;
  right: 0px;
  background: rgba(255, 255, 255, 0.8);
  text-align: center;
  font-size: 40px;
  align-items: center;
  justify-content: center;
  display: flex;
}
.side-bottom :hover,
.side-bottom2:hover {
  color: var(--el-color-primary);
}
.side-bottom {
  margin-left: -35px;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  cursor: pointer;
  background: rgba(0, 0, 0, 0.2);
  text-align: center;
  position: absolute;
  top: 50%;
  z-index: 9999;
}
.side-bottom2 {
  margin-left: -20px;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  cursor: pointer;
  background: rgba(0, 0, 0, 0.2);
  position: absolute;
  top: 50%;
  left: 100%;
  z-index: 9999;
}
.side-bottom2 i,
.side-bottom i {
  margin-top: 12px;
  margin-left: 8px;
  font-size: 14px;
}
.luckysheet-cs-draghandle {
  display: none !important;
}
</style>
  